import path from 'path'
import fs from 'fs';
import { resolve, join } from 'path';
import process from "child_process"
import { fileURLToPath } from 'url';
import { matchFileType, toArray } from "../utils"

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// 获取插件根目录
const pluginDir = resolve(__dirname, "..")
// 插件内的webp命令工具
const command = join(pluginDir, 'libwebp', 'bin', 'cwebp.exe')

let webpInfo = {};

export function isDirectory(abs){
    return fs.statSync(abs).isDirectory();
}

export function isExclude(abs, exclude, cwd){
    exclude = toArray(exclude)
    if(exclude.length){
        for(let i = 0; i < exclude.length; i++){
            const excludePath = path.join(cwd, exclude[i])
            if(abs.indexOf(excludePath) === 0){
                return true
            }
        }        
    }
    return false
}

export const imageToWebp = function (filePath, quality) {
    let nPath = `${filePath}.webp`;
    
    // 读取原文件的信息
    const fileName = path.basename(filePath);
    const sImgStat = fs.statSync(filePath);

    if(fs.existsSync(nPath)){
        // 如果对应的webp文件已经存在，比较webp文件与原图片的更新时间，webp文件的更新时间晚于原图片文件的更新时间则直接读取文件内容返回
        const stat = fs.statSync(nPath);

        const webpMTime = stat.mtime.getTime();
        const sImgMTime = sImgStat.mtime.getTime();

        if(webpMTime > sImgMTime){
            let imageData = fs.readFileSync(nPath);     
            if(stat.size > sImgStat.size){
                return { fileName: fileName, filepath:nPath, file: imageData, isMin: false}
            }

            return { fileName: fileName, filepath:nPath, file: imageData, isMin: true }
        }
    }

    // 重新转成新的webp文件
    const execCommand = `${command} -q ${quality} ${filePath} -o ${nPath}`;

    process.execSync(execCommand);
    if(fs.existsSync(nPath)){
        const stat = fs.statSync(nPath);
        const imageData = fs.readFileSync(nPath);
        return { fileName: fileName, filepath:nPath, file: imageData, isMin: (stat.size < sImgStat.size)}
    }else{
        return null
    }      
}

export const scanAssets =  function (config){
    const { assets, exclude, imageTypes, quality, cwd } = config;

    console.info(`scanAssets ${imageTypes} in ${assets}...`)
    if (fs.existsSync(assets) === false) {
        return;
    }

    const files = fs.readdirSync(assets);
    files.forEach((v) => {

        const abs = path.join(assets, v);
        const iexl = isExclude(abs, exclude, cwd)

        if (isDirectory(abs) && !iexl) {
            const c = JSON.parse(JSON.stringify(config))
            c.assets = abs;
            scanAssets(c);
        } else if (matchFileType(abs, imageTypes)) {
            const res = imageToWebp(abs, quality)
            if(res){
                webpInfo[res.fileName] = res;
                console.info(`convert file ${abs} to webp success...`)
            }
        }
    })

    return webpInfo
}